﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace myCalc
{
    public partial class FormCalc : Form
    {
        private double _num1 = 0, _num2 = 0, _result = 0, _judgeLastOp=0;
        private string _numCode = "dec";

        private string _operator = "";

        public string DecToBin(int dec)
        {
            int abs_dec = Math.Abs(dec);
            string bin = "";
            while (abs_dec >= 2)
            {
                bin = Convert.ToChar(abs_dec % 2 + '0') + bin;
                abs_dec = abs_dec / 2;
            }
            bin = Convert.ToChar(abs_dec + '0') + bin;

            if (dec >= 0) return bin;
            else return "-" + bin;
        }

        public int BinToDec(string bin)
        {
            string firstChar = bin.Substring(0, 1);
            string abs_bin = bin;
            if (firstChar == "-") abs_bin = bin.Substring(1, bin.Length - 1);
            int dec = 0;
            for (int i = abs_bin.Length; i >= 1; i--)
            {
                dec = dec + Convert.ToInt32(abs_bin[i - 1] - '0') * (int)(Math.Pow(2, abs_bin.Length - i));
            }
            if (firstChar == "-") return -dec;
            else return dec;
        }

        public string DecToOct(int dec)
        {
            int abs_dec = Convert.ToChar(dec);
            string oct = "";
            while (abs_dec >= 8)
            {
                oct = Convert.ToChar(abs_dec % 8 + '0') + oct;
                abs_dec = abs_dec / 8;
            }
            oct = Convert.ToChar(abs_dec + '0') + oct;

            if (dec >= 0) return oct;
            else return "-" + oct;
        }

        public int OctToDec(string oct)
        {
            string firstChar = oct.Substring(0, 1);
            string abs_oct = oct;
            if (firstChar == "-") abs_oct = oct.Substring(1, oct.Length - 1);
            int dec = 0;
            for (int i = abs_oct.Length; i >= 1; i--)
            {
                dec = dec + Convert.ToInt32(abs_oct[i - 1] - '0') * (int)(Math.Pow(8, abs_oct.Length - i));
            }
            if (firstChar == "-") return -dec;
            else return dec;
        }


        public FormCalc()
        {
            InitializeComponent();
        }

        private void FormCalc_Load(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void butNum1_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "1";
        }

        private void butNum2_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "2";
        }

        private void butNum3_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "3";
        }

        private void butNum4_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "4";
        }

        private void butNum5_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "5";
        }

        private void butNum6_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "6";
        }

        private void butNum7_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "7";
        }

        private void butNum8_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "8";
        }

        private void butNum9_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "9";
        }

        private void butNum0_Click(object sender, EventArgs e)
        {
            if (_judgeLastOp == 1)
            {
                textBox.Text = "";
                _judgeLastOp = 0;
            }
            textBox.Text = textBox.Text + "0";
        }

        private void butPoint_Click(object sender, EventArgs e)
        {
            if (textBox.Text.IndexOf('.') == -1)
            {
                textBox.Text = textBox.Text + ".";
            }
            
        }

        private void butSum_Click(object sender, EventArgs e)
        {
            _judgeLastOp = 1;
            
            if (_operator == "+")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) + _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) + _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) + _num1;
            }
            else if (_operator == "-")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) - _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) - _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) - _num1;
            }
            else if (_operator == "*")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) * _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) * _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) * _num1;
            }
            else if (_operator == "/")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) / _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) / _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) / _num1;
            }
            else
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text);
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text);
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text);
            }
            _operator = "+";
            textBox.Text = "";
            if (_numCode == "dec")
                textBox.Text = _num1.ToString();
            else if (_numCode == "bin")
                textBox.Text = DecToBin((int)Math.Round(_num1));
            else if (_numCode == "oct")
                textBox.Text = DecToOct((int)Math.Round(_num1));
        }

        private void butSub_Click(object sender, EventArgs e)
        {
            _judgeLastOp = 1;
            if (_operator == "+")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) + _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) + _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) + _num1;
            }
            else if (_operator == "-")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) - _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) - _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) - _num1;
            }
            else if (_operator == "*")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) * _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) * _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) * _num1;
            }
            else if (_operator == "/")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) / _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) / _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) / _num1;
            }
            else
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text);
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text);
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text);
            }
            _operator = "-";
            textBox.Text = "";
            if (_numCode == "dec")
                textBox.Text = _num1.ToString();
            else if (_numCode == "bin")
                textBox.Text = DecToBin((int)Math.Round(_num1));
            else if (_numCode == "oct")
                textBox.Text = DecToOct((int)Math.Round(_num1));
        }

        private void butMul_Click(object sender, EventArgs e)
        {
            _judgeLastOp = 1;
            if (_operator == "+")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) + _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) + _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) + _num1;
            }
            else if (_operator == "-")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) - _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) - _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) - _num1;
            }
            else if (_operator == "*")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) * _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) * _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) * _num1;
            }
            else if (_operator == "/")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) / _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) / _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) / _num1;
            }
            else
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text);
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text);
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text);
            }
            _operator = "*";
            textBox.Text = "";
            if (_numCode == "dec")
                textBox.Text = _num1.ToString();
            else if (_numCode == "bin")
                textBox.Text = DecToBin((int)Math.Round(_num1));
            else if (_numCode == "oct")
                textBox.Text = DecToOct((int)Math.Round(_num1));
        }

        private void butDiv_Click(object sender, EventArgs e)
        {
            _judgeLastOp = 1;
            if (_operator == "+")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) + _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) + _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) + _num1;
            }
            else if (_operator == "-")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) - _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) - _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) - _num1;
            }
            else if (_operator == "*")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) * _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) * _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) * _num1;
            }
            else if (_operator == "/")
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text) / _num1;
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text) / _num1;
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text) / _num1;
            }
            else
            {
                if (_numCode == "dec")
                    _num1 = Convert.ToDouble(textBox.Text);
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBox.Text);
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBox.Text);
            }
            _operator = "/";
            textBox.Text = "";
            if (_numCode == "dec")
                textBox.Text = _num1.ToString();
            else if (_numCode == "bin")
                textBox.Text = DecToBin((int)Math.Round(_num1));
            else if (_numCode == "oct")
                textBox.Text = DecToOct((int)Math.Round(_num1));
        }

        private void butPower_Click(object sender, EventArgs e)
        {
            if (textBox.Text.Length > 0)
            {
                string firstChar = textBox.Text.Substring(0, 1);
                if (firstChar == "-") textBox.Text = "+" + textBox.Text.Substring(1, textBox.Text.Length - 1);
                else if (firstChar == "+") textBox.Text = "-" + textBox.Text.Substring(1, textBox.Text.Length - 1);
                else textBox.Text = "-" + textBox.Text;
            }
        }

        private void butClear_Click(object sender, EventArgs e)
        {
            _num1 = 0;
            _num2 = 0;
            _operator = "";
            textBox.Text = "";
            _result = 0;
            textBox.Text = "0";
        }

        private void butEqual_Click(object sender, EventArgs e)
        {
            if (_numCode == "dec")
                _num2 = Convert.ToDouble(textBox.Text);
            else if (_numCode == "bin")
                _num2 = BinToDec(textBox.Text);
            else if (_numCode == "oct")
                _num2 = OctToDec(textBox.Text);
            textBox.Text = "";
            if (_operator == "+")
            {
                _result = _num1 + _num2;
            }
            else if (_operator == "-")
            {
                _result = _num1 - _num2;
            }
            else if (_operator == "*")
            {
                _result = _num1 * _num2;
            }
            else if (_operator == "/")
            {
                _result = _num1 / _num2;
            }

            if (_numCode == "dec")
                textBox.Text = _result.ToString();
            else if (_numCode == "bin")
                textBox.Text = DecToBin((int)Math.Round(_result));
            else if (_numCode == "oct")
                textBox.Text = DecToOct((int)Math.Round(_result));
        }

        private void butDel_Click(object sender, EventArgs e)
        {
            if (textBox.Text.Length > 0)
            {
                textBox.Text = textBox.Text.Substring(0, textBox.Text.Length - 1);
            }

            if (textBox.Text == "" || textBox.Text == "+" || textBox.Text == "-")
                textBox.Text = "0";
        }

        private void FormCalc_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '0') butNum0.PerformClick();
            else if (e.KeyChar == '1') butNum1.PerformClick();
            else if (e.KeyChar == '2') butNum2.PerformClick();
            else if (e.KeyChar == '3') butNum3.PerformClick();
            else if (e.KeyChar == '4') butNum4.PerformClick();
            else if (e.KeyChar == '5') butNum5.PerformClick();
            else if (e.KeyChar == '6') butNum6.PerformClick();
            else if (e.KeyChar == '7') butNum7.PerformClick();
            else if (e.KeyChar == '8') butNum8.PerformClick();
            else if (e.KeyChar == '9') butNum9.PerformClick();
            else if (e.KeyChar == '+') butSum.PerformClick();
            else if (e.KeyChar == '-') butSub.PerformClick();
            else if (e.KeyChar == '*') butMul.PerformClick();
            else if (e.KeyChar == '/') butDiv.PerformClick();
            else if (e.KeyChar == '.') butPoint.PerformClick();
            else if (e.KeyChar == 'c') butClear.PerformClick();
            else if (e.KeyChar == (char)Keys.Back) butDel.PerformClick();
            else if (e.KeyChar == '=') butEqual.PerformClick();
            textBox.Select(textBox.Text.Length, 0);
        }

        private void radioButDeci_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButDeci.Checked == true)
            {
                if (textBox.Text == ".") textBox.Text = "0.0";
                if (textBox.Text != "")
                {
                    if (_numCode == "bin") textBox.Text = BinToDec(textBox.Text).ToString();
                    else if (_numCode == "oct") textBox.Text = OctToDec(textBox.Text).ToString();
                }
                butNum0.Enabled = true;
                butNum1.Enabled = true;
                butNum2.Enabled = true;
                butNum3.Enabled = true;
                butNum4.Enabled = true;
                butNum5.Enabled = true;
                butNum6.Enabled = true;
                butNum7.Enabled = true;
                butNum8.Enabled = true;
                butNum9.Enabled = true;
                butPoint.Enabled = true;
                _numCode = "dec";
            }
        }

        private void radioButBin_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButBin.Checked == true)
            {
                if (textBox.Text == ".") textBox.Text = "0.0";
                if (textBox.Text != "")
                {
                    if (_numCode == "dec") textBox.Text = DecToBin((int)Math.Round(Convert.ToDouble(textBox.Text)));
                    else if (_numCode == "oct")
                    {
                        int dec = OctToDec(textBox.Text);
                        textBox.Text = DecToOct(dec);
                    }
                }
                butNum0.Enabled = true;
                butNum1.Enabled = true;
                butNum2.Enabled = false;
                butNum3.Enabled = false;
                butNum4.Enabled = false;
                butNum5.Enabled = false;
                butNum6.Enabled = false;
                butNum7.Enabled = false;
                butNum8.Enabled = false;
                butNum9.Enabled = false;
                butPoint.Enabled = false;
                _numCode = "bin";
            }
        }

        private void radioButOct_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButOct.Checked == true)
            {
                if (textBox.Text == ".") textBox.Text = "0.0";
                if (textBox.Text != "")
                {
                    if (_numCode == "dec") textBox.Text = DecToOct((int)Math.Round(Convert.ToDouble(textBox.Text)));
                    else if (_numCode == "bin")
                    {
                        int dec = BinToDec(textBox.Text);
                        textBox.Text = DecToOct(dec);
                    }
                }
                butNum0.Enabled = true;
                butNum1.Enabled = true;
                butNum2.Enabled = true;
                butNum3.Enabled = true;
                butNum4.Enabled = true;
                butNum5.Enabled = true;
                butNum6.Enabled = true;
                butNum7.Enabled = true;
                butNum8.Enabled = false;
                butNum9.Enabled = false;
                butPoint.Enabled = false;
                _numCode = "oct";
            }
        }

    }
}
